/********************************************************
* @file: IMO3D.cpp
* @date: 09/09/2009
********************************************************
* acmFrame
********************************************************/

// includes
//----------
#include "imo3d.h"
#include "./geometry/curves/curvefactory.h"
// #include "../control/mgControl.h"


// initializations
//-----------------
IMO3D* IMO3D::m_imo3d = NULL;


//
//////////////////////////////////////////////////////////////////////////
IMO3D::IMO3D()
: m_initializationStatus( false )
, m_idSurf( -1 ) 
, m_objdraw( NULL )
, m_currCurve( NULL )
, m_endAction( NULL )
{
}

//
//////////////////////////////////////////////////////////////////////////
IMO3D::~IMO3D()
{
  if( m_objdraw != NULL )
    delete m_objdraw;
}


//
//////////////////////////////////////////////////////////////////////////
IMO3D&
IMO3D::instance()
{
  if( !m_imo3d )
  {
    m_imo3d = new IMO3D();
  }
  return *m_imo3d;
}


//
//////////////////////////////////////////////////////////////////////////
void
 IMO3D::setEndAction(void *obj, void (*endAction)(void *obj, Curve *cv, int _idSurf))
{
  m_endAction = endAction;
  m_objClass  = obj;
}

//
//////////////////////////////////////////////////////////////////////////
void 
IMO3D::setDrawCurve( drawGRA *_obj )
{
  m_objdraw = _obj;
}

//
//////////////////////////////////////////////////////////////////////////
int
IMO3D::beginCreate( char *_type )
{
  if( m_currCurve != NULL )
    delete m_currCurve;
  m_currCurve = NULL;
  m_idSurf = -1;

  if (strcmp (_type, "line") == 0)
  {
    m_currCurve = CurveFactory::create( Curve::LINE );
  } 
  else if (strcmp (_type, "polyline") == 0)
  {
    m_currCurve = CurveFactory::create( Curve::POLYLINE );
  }
  else if (strcmp (_type, "arc") == 0)
  {
    m_currCurve = CurveFactory::create( Curve::ARC );
  }
  else if (strcmp (_type, "spline") == 0)
  {
    m_currCurve = CurveFactory::create( Curve::SPLINE );
  }

  if (m_currCurve != NULL)
  {
    m_currCurve->setDraw(m_objdraw);
  }
  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::beginCreate( char *_type, const vector<Point3D>& _addp )
{
  if (!beginCreate (_type))
    return 0;
  m_idSurf = -1;

  m_currCurve->beginAddPoint(_addp);

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::beginCreate( char *_type, double _x, double _y, double _z )
{
  if (!beginCreate (_type))
    return 0;

  m_currCurve->beginAddPoint(_x, _y, _z);

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::addTempPoint( double _x, double _y, double _z )
{
  if (m_currCurve == NULL)
    return 0;

  m_currCurve->addTempPoint(_x, _y, _z);

  xtmp = _x;
  ytmp = _y;
  ztmp = _z;

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::addTempOrthoPoint( double _x, double _y, double _z )
{
  if (m_currCurve == NULL)
    return 0;

  m_currCurve->addTempOrthoPoint(_x, _y, _z);

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
Point3D 
IMO3D::getLastTempPoint()
{
  return m_currCurve->getLastTempPoint();
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::addPoint( double _x, double _y, double _z )
{
  if( m_currCurve == NULL )
    return 0;

  m_currCurve->addPoint(_x, _y, _z);

  // call register function to create a line if it is possible
  if( m_currCurve->getType() == Curve::LINE )
  {
    if( m_currCurve->possible() )
    {
      m_endAction(m_objClass, m_currCurve, m_idSurf); // create curve
      //B:18/02 -> the next two statements were missing:
      releaseCurrCurve();
      beginCreate("line");
    }
  }
  else if( m_currCurve->getType() == Curve::ARC )
  {
    if( m_currCurve->possible() )
    {
      m_endAction(m_objClass, m_currCurve, m_idSurf); // create curve
      //B:18/02 -> the next two statements were missing:
      releaseCurrCurve();
      IMO.beginCreate( "arc", 0.0, 0.0, 1.0 );
    }
  }

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
int 
IMO3D::endAddPoint()
{
  if( m_currCurve == NULL )
    return 0;

  m_currCurve->endAddPoint();

  // create curve
  if( m_currCurve->possible() )
    m_endAction(m_objClass, m_currCurve, m_idSurf ); // create curve
  releaseCurrCurve();

  // forget about surface embeeded status of curve (05/02/2010: Ricardo Marques)
  m_idSurf = -1;

  return 1;
}

//
//////////////////////////////////////////////////////////////////////////
Curve* 
IMO3D::getCurrCurve()
{
  return m_currCurve;
}

//
//////////////////////////////////////////////////////////////////////////
void 
IMO3D::drawCurrCurve()
{
  if (m_currCurve == NULL)
    return;

  m_currCurve->addTempPoint(xtmp, ytmp, ztmp);
  m_currCurve->draw();
}

//
//////////////////////////////////////////////////////////////////////////
void 
IMO3D::releaseCurrCurve()
{
  if (m_currCurve != NULL)
    delete m_currCurve;
  m_currCurve = NULL;
}
